package cn.maihe.elg.operation.centers.hymake.handler.service;

import cn.maihe.elg.operation.centers.hymake.config.HyMakeInfoConfig;
import cn.maihe.elg.operation.centers.hymake.dto.HyMakeBaseRespDTO;
import cn.maihe.elg.operation.centers.hymake.dto.handler.HyMakeRevokeApplyReqDTO;
import cn.maihe.elg.operation.centers.hymake.handler.HyMakeCenterTradeService;
import cn.maihe.elg.operation.centers.supports.CenterTradeContext;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.model.enums.*;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.ProjectInfoDO;
import cn.maihe.elg.operation.repository.entity.RevokeOrderAttachmentDO;
import cn.maihe.elg.operation.repository.entity.RevokeOrderInfo;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.service.order.RevokeOrderInfoService;
import cn.maihe.elg.operation.utils.IdGenerate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Description 保函撤销申请
 * @Author caixh
 * @Date 2022/3/30.
 */
@CenterTradeService(
        provider = CenterProviderEnum.HYMAKE,
        centerNo = CenterNoEnum.NINGDE,
        tradeType = TradeType.lstSurrend,
        reqClass = HyMakeRevokeApplyReqDTO.class,
        respClass = HyMakeBaseRespDTO.class
)
@Slf4j
public class HyMakeRevokeApplyService extends HyMakeCenterTradeService<HyMakeRevokeApplyReqDTO, HyMakeBaseRespDTO> {

    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;
    @Resource
    private ProjectInfoService projectInfoService;
    @Resource
    private RevokeOrderInfoService revokeOrderInfoService;

    public HyMakeRevokeApplyService(HyMakeInfoConfig centerInfosConfig) {
        super(centerInfosConfig);
    }

    /**
     * 具体业务处理
     *
     * @param context
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public HyMakeBaseRespDTO processService(CenterTradeContext<HyMakeRevokeApplyReqDTO, HyMakeBaseRespDTO> context) {

        HyMakeRevokeApplyReqDTO req = context.getReq();
        Long centerId = context.getCenterId();
        Long orgId = context.getOrgId();
        String revokeNo = req.getPolicyNo();

        AcceptOrderInfoDO orderInfoDO = acceptOrderInfoService.getByGuaranteeNo(centerId, orgId, revokeNo);
        if (orderInfoDO == null) {
            return HyMakeBaseRespDTO.error("查无此投保申请记录");
        }
        RevokeFlagEnum flagEnum = RevokeFlagEnum.resolve(orderInfoDO.getRevokeFlag());
        if (flagEnum == RevokeFlagEnum.SUCCESS ) {
            return HyMakeBaseRespDTO.error("退保状态为[" + flagEnum + "]，不能再申请退保");
        }
        if (flagEnum == RevokeFlagEnum.PROCESSING) {
            return HyMakeBaseRespDTO.error("退保审核中，请耐心等待审核结果");
        }
        if (flagEnum != RevokeFlagEnum.INIT && flagEnum != RevokeFlagEnum.FAILURE) {
            return HyMakeBaseRespDTO.error("退保状态不是待退保状态，不能申请退保");
        }

        if (orderInfoDO.getStatus() == AcceptOrderStatus.FINISH.getStatus()) {
            return HyMakeBaseRespDTO.error("保函已完成，不能退保申请");
        }
        if (orderInfoDO.getStatus() == AcceptOrderStatus.CANCEL.getStatus()) {
            return HyMakeBaseRespDTO.error("保函已取消，不能退保申请");
        }
        if (orderInfoDO.getStatus() != AcceptOrderStatus.HAS_OUT_GUARANTEE.getStatus()&&orderInfoDO.getStatus() != AcceptOrderStatus.REVOKE_FAIL.getStatus()) {
            return HyMakeBaseRespDTO.error("已出函状态才能发起退保，未出函前可调用放弃投保申请");
        }


        AcceptOrderInfoDO updateOrderInfo = AcceptOrderInfoDO.builder().id(orderInfoDO.getId())
                .status(AcceptOrderStatus.REVOKE_PROCESSING.getStatus())
                .revokeFlag(RevokeFlagEnum.PROCESSING.getFlag()).remark(req.getBackReasonDetail()).build();
//        acceptOrderInfoService.updateById(updateOrderInfo);

        ProjectInfoDO project = projectInfoService.selectById(orderInfoDO.getProjectId());

        RevokeOrderInfo revokeOrderInfo = RevokeOrderInfo.builder()
                .id(IdGenerate.getId())
                .centerId(centerId)
                .orgId(orgId)
                //通过保函编号关联受理订单号
                .revokeNo(revokeNo)
                .note(req.getBackReasonDetail())
                //备注字段存储 业务流水号
                .remark(req.getPolicyNo())
                .projectCode(project.getProjectCode()).projectName(orderInfoDO.getProjectName())
                .sectionCode(project.getSectionCode()).sectionName(orderInfoDO.getSectionName())
                .tenderer(project.getTenderer()).status(0)
                .bankName(req.getBankName())
                .accountName(req.getAccountName())
                .openBankName(req.getOpenBankName())
                .bankCardNum(req.getBankCardNum())
                .backPremium(req.getBackPremium()==null?0L:(new BigDecimal(req.getBackPremium()).multiply(new BigDecimal("100")).longValue()))
                .build();
        List<RevokeOrderAttachmentDO> attachmentDOS = null;
        if(req.getBackFileList()!=null){
            AtomicInteger index=new AtomicInteger(1);
            attachmentDOS = req.getBackFileList().stream().map(item -> {
                return RevokeOrderAttachmentDO.builder()
                        .revokeOrderId(revokeOrderInfo.getId())
                        .no(index.getAndIncrement())
                        .fileUrl(item.getBackFileUrl())
                        .fileName(item.getBackFileName())
                        .fileMd5(item.getBackFileMD5())
                        .build();
            }).collect(Collectors.toList());
        }

        revokeOrderInfoService.saveRevokeOrderInfo(revokeOrderInfo,attachmentDOS,updateOrderInfo);

        return HyMakeBaseRespDTO.success("退保申请已受理,请耐心等待审核结果通知");
    }
}
